package thread;

import java.util.concurrent.locks.LockSupport;

/**
 * Park/unpark的使用
 */
public class ParkDemo {

    Object food = null;

    /**
     * 正常情况下
     * @throws InterruptedException
     */
    void normal() throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (food == null) {
                System.out.println("没有包子，等待");
                LockSupport.park();
            }
            System.out.println("买到包子，回家");
        });
        thread.start();
        Thread.sleep(1000);
        food = new Object();
        System.out.println("生产了包子，通知");
        LockSupport.unpark(thread);
    }

    /**
     * 错过通知，没有问题
     * @throws InterruptedException
     */
    void missNotify() throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (food == null) {
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("没有包子，等待");
                LockSupport.park();
            }
            System.out.println("买到包子，回家");
        });
        thread.start();
        Thread.sleep(1000);
        food = new Object();
        System.out.println("生产了包子，通知");
        LockSupport.unpark(thread);
    }

    /**
     * 使用了 monitor， park不会释放monitor， 死锁
     * @throws InterruptedException
     */
    void useMonitor() throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (food == null) {
                System.out.println("没有包子，等待");
                synchronized (this) {
                    LockSupport.park();
                }
            }
            System.out.println("买到包子，回家");
        });
        thread.start();
        Thread.sleep(1000);
        food = new Object();
        synchronized (this) {
            System.out.println("生产了包子，通知");
            LockSupport.unpark(thread);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ParkDemo d = new ParkDemo();
//        d.normal();
//        d.missNotify();
        d.useMonitor();
    }
}
